//
// Copyright (C) 2024 Kumo inc.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#include <turbo/flags/flag.h>
#include <turbo/bootstrap/servlet.h>
#include <turbo/log/logging.h>
#include <krpc/rpc/server.h>
#include <hadarservice/service.h>
#include <hadarservice/engine.h>

TURBO_FLAG(int32_t, port, 8801, "TCP Port of this server");
TURBO_FLAG(std::string, listen_addr, "", "Server listen address, may be IPV4/IPV6/UDS."
                                         " If this is set, the flag port will be ignored");
TURBO_FLAG(std::string, dict_root, "", "convert dict root directory path");
TURBO_FLAG(int32_t, idle_timeout_s, -1, "Connection will be closed if there is no "
                                        "read/write operations during the last `idle_timeout_s'");
int main(int argc, char *argv[]) {
    auto &servlet = turbo::Servlet::instance();
    auto *app = servlet.run_app();
    app->add_option("-p,--port", FLAGS_port, "TCP Port of this server");
    app->add_option("-l,--listen_addr", FLAGS_listen_addr, "Server listen address, may be IPV4/IPV6/UDS."
                                                           " If this is set, the flag port will be ignored");
    app->add_option("-i,--idle", FLAGS_idle_timeout_s, "Connection will be closed if there is no "
                                                       "read/write operations during the last `idle_timeout_s'");

    app->add_option("-d,--dict_root", FLAGS_dict_root, "convert dict root directory path.");

    auto [ext, code] = servlet.run(argc, argv);
    if(ext) {
        return code;
    }

    hadarservice::ConvertEngine &engine = hadarservice::ConvertEngine::instance();
    auto irs = engine.initailize(turbo::get_flag(FLAGS_dict_root));
    if(!irs.ok()) {
      std::cerr << irs.message() << "\n";
      exit(1);
    }
    // Generally you only need one Server.
    krpc::Server server;

    // Instance of your service.
    hadarservice::ServiceImpl echo_service_impl;

    // Add the service into server. Notice the second parameter, because the
    // service is put on stack, we don't want server to delete it, otherwise
    // use melon::SERVER_OWNS_SERVICE.
    if (server.AddService(&echo_service_impl,
                          krpc::SERVER_DOESNT_OWN_SERVICE) != 0) {
        LOG(ERROR) << "Fail to add service";
        return -1;
    }

    kutil::EndPoint point;
    if (!turbo::get_flag(FLAGS_listen_addr).empty()) {
        if (kutil::str2endpoint(turbo::get_flag(FLAGS_listen_addr).c_str(), &point) < 0) {
            LOG(ERROR) << "Invalid listen address:" << turbo::get_flag(FLAGS_listen_addr);
            return -1;
        }
    } else {
        point = kutil::EndPoint(kutil::IP_ANY, turbo::get_flag(FLAGS_port));
    }
    // Start the server.
    krpc::ServerOptions options;
    options.idle_timeout_sec = turbo::get_flag(FLAGS_idle_timeout_s);
    if (server.Start(point, &options) != 0) {
        LOG(ERROR) << "Fail to start EchoServer";
        return -1;
    }

    // Wait until Ctrl-C is pressed, then Stop() and Join() the server.
    server.RunUntilAskedToQuit();
    return 0;
}
